#include "slm/aabb.h"
#include <algorithm>
//! declare namespace
SLMATH_BEGIN()

aabb::aabb(const slm::vec3& min_c/* = slm::vec3(0.0f)*/,
	const slm::vec3 max_c/* = slm::vec3(0.0f)*/)
	:m_minCorner(min_c),
	m_maxCorner(max_c)
{
	_Update_Center();
}

aabb::aabb(const aabb& rhs)
{
	m_minCorner = rhs.m_minCorner;
	m_maxCorner = rhs.m_maxCorner;
	m_Center = rhs.m_Center;
}

void aabb::Merge(const slm::vec3& pos)
{
	m_minCorner.x = std::min(m_minCorner.x, pos.x);
	m_minCorner.y = std::min(m_minCorner.y, pos.y);
	m_minCorner.z = std::min(m_minCorner.z, pos.z);

	m_maxCorner.x = std::max(m_maxCorner.x, pos.x);
	m_maxCorner.y = std::max(m_maxCorner.y, pos.y);
	m_maxCorner.z = std::max(m_maxCorner.z, pos.z);

	_Update_Center();
}

void aabb::Merge(const aabb& _aabb)
{
	Merge(_aabb.GetMinCorner());
	Merge(_aabb.GetMaxCorner());
}

bool aabb::operator== (const aabb& _aabb)
{
	if (m_minCorner == _aabb.m_minCorner && m_maxCorner == _aabb.m_maxCorner)
		return true;
	return false;
}

void aabb::GetCorner(vec3 corner[CORNER_NUMBER])const
{
	corner[0] = m_minCorner;
	corner[1].x = m_minCorner.x; corner[1].y = m_maxCorner.y; corner[1].z = m_minCorner.z;
	corner[2].x = m_maxCorner.x; corner[2].y = m_maxCorner.y; corner[2].z = m_minCorner.z;
	corner[3].x = m_maxCorner.x; corner[3].y = m_minCorner.y; corner[3].z = m_minCorner.z;            

	corner[4] = m_maxCorner;
	corner[5].x = m_minCorner.x; corner[5].y = m_maxCorner.y; corner[5].z = m_maxCorner.z;
	corner[6].x = m_minCorner.x; corner[6].y = m_minCorner.y; corner[6].z = m_maxCorner.z;
	corner[7].x = m_maxCorner.x; corner[7].y = m_minCorner.y; corner[7].z = m_maxCorner.z;
}

void aabb::_Update_Center()
{
	m_Center.x = (m_minCorner.x + m_maxCorner.x) / 2.0f;
	m_Center.y = (m_minCorner.y + m_maxCorner.y) / 2.0f;
	m_Center.z = (m_minCorner.z + m_maxCorner.z) / 2.0f;
}
SLMATH_END()
